package com.yuanchu.auth.config;

import com.yuanchu.auth.exception.AuthWebResponseExceptionTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import javax.annotation.Resource;

/**
 * @author Mr.M
 * @version 1.0
 * @description 授权服务器配置
 * @date 2022/9/26 22:25
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    @Resource(name = "authorizationServerTokenServicesCustom")
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Autowired
    private AuthenticationManager authenticationManager;


    // 客户端详情服务
    @Override
    public void configure(ClientDetailsServiceConfigurer clients)
            throws Exception {
        clients.inMemory()// 使用in-memory存储
                .withClient("XcWebApp")// client_id
//                .secret("secret")//客户端密钥
                .secret(new BCryptPasswordEncoder().encode("XcWebApp"))//客户端密钥
                .resourceIds("xuecheng-plus", "yaunchu-system")//资源列表
                .authorizedGrantTypes("authorization_code", "password","client_credentials","implicit","refresh_token")
                // 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials
                .scopes("all")// 允许的授权范围
                .autoApprove(false)//false跳转到授权页面
                //客户端接收授权码的重定向地址
                .redirectUris("http://www.51xuecheng.cn")
        ;
    }


    // 令牌端点的访问配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .authenticationManager(authenticationManager)// 认证管理器
                // token 持久化
                .tokenServices(authorizationServerTokenServices)// 令牌管理服务
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
        // 自定义异常翻译器
        endpoints.exceptionTranslator(new AuthWebResponseExceptionTranslator());
        //配置增强TOKEN
        // endpoints.accessTokenConverter(accessTokenConverter());
    }

    // 令牌端点的安全配置
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security
                .tokenKeyAccess("permitAll()")                    // oauth/token_key是公开
                .checkTokenAccess("permitAll()")                  // oauth/check_token公开
                .allowFormAuthenticationForClients()                // 表单认证（申请令牌）
        ;
    }

    /**
     * token增强器
     * @return
     */
/*
    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(){
            @Override
            public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
                // 这里的UserName是OpenId
                String username = authentication.getUserAuthentication().getName();
                // 得到用户名，去处理数据库可以拿到当前用户的信息和角色信息（需要传递到服务中用到的信息）
                // final Map<String, Object> addToJWTInformation = new HashMap<>();
                // JSONObject json = new JSONObject();
                // json.put("userId", 1);  //这里直接写死的
                // json.put("userName", username); //直接写死的
                // addToJWTInformation.put("localUser", json.toJSONString());
                // ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(addToJWTInformation);
                // OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
                YoshopStoreUserEntity user = JSON.parseObject(username, YoshopStoreUserEntity.class);
                final Map<String, Object> addToJWTInformation = new HashMap<>();
                addToJWTInformation.put("userId", user.getStoreUserId());
                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(addToJWTInformation);
                OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
                return enhancedToken;
            }
        };
        return accessTokenConverter;
    }
*/

}
